package io.kubesphere.devops.service.impl;

import io.kubesphere.devops.common.PhaseTwoTransactionHandler;
import io.kubesphere.devops.controller.OperationResponse;
import io.kubesphere.devops.controller.MergeRequestDTO;
import io.kubesphere.devops.core.DynamicDataSourceContextHolder;
import io.kubesphere.devops.core.RuleExecutor;
import io.kubesphere.devops.dao.UserMergingRuleDao;
import io.kubesphere.devops.model.MergeAction;
import io.kubesphere.devops.model.UserMerging;
import io.kubesphere.devops.model.UserMergingRule;
import io.kubesphere.devops.service.MergeLogService;
import io.kubesphere.devops.service.MergeManageService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.sql.SQLException;
import java.util.List;

/**
 * <p> MergeManageServiceImpl
 *
 * @author gaochuan
 * @version 0.1.0
 * @date 2021/11/16 14:23
 * @since 2021/11/16
 */
@Service
@Slf4j
public class MergeManageServiceImpl implements MergeManageService {

    private final MergeLogService mergeLogService;

    private final PhaseTwoTransactionHandler phaseTwoTransactionHandler;

    private final UserMergingRuleDao userMergingRuleDao;

    public MergeManageServiceImpl(MergeLogService mergeLogService, PhaseTwoTransactionHandler phaseTwoTransactionHandler, UserMergingRuleDao userMergingRuleDao) {
        this.mergeLogService = mergeLogService;
        this.phaseTwoTransactionHandler = phaseTwoTransactionHandler;
        this.userMergingRuleDao = userMergingRuleDao;
    }

    @Override
    public OperationResponse merge(MergeRequestDTO mergeRequestDTO) throws Exception {
        DynamicDataSourceContextHolder.routeMaster();
        return doMerge(mergeRequestDTO);

    }

    private OperationResponse doMerge(MergeRequestDTO mergeRequestDTO) throws Exception {
        //记录日志
        UserMerging merging = mergeLogService.mergeLog();
        List<UserMergingRule> rules = userMergingRuleDao.getAll();
        OperationResponse response = OperationResponse.builder().success(true).message("合并成功").build();
        for (UserMergingRule rule : rules) {
            try {
                RuleExecutor.loadExecutorRule(rule.getMergeRuleFunction()).process(mergeRequestDTO.getSourceIdentificationId(), mergeRequestDTO.getTargetIdentificationId(), rule);
            } catch (SQLException throwables) {
                response.setSuccess(false);
                response.setMessage("合并时发生异常,异常原因 ==>" + throwables.getMessage());
                break;
            }
        }
        if (!response.isSuccess()) {
            try {
                this.phaseTwoRollback(merging.getUserMergingId());
            } catch (Exception exception) {
                response.setMessage(response.getMessage() + " 二阶段补偿失败,需人工干预重试");
            }
            response.setMessage(response.getMessage() + " 二阶段补偿成功,数据被回滚");
        }

        return response == null ? OperationResponse.builder().success(true).message("合并成功").build() : response;
    }

    @Override
    public OperationResponse phaseTwoCommit(String xid) {
        DynamicDataSourceContextHolder.routeMaster();
        MergeAction action = mergeLogService.queryMergeAction(xid);
        phaseTwoTransactionHandler.commit(action);
        return OperationResponse.builder().success(true).message("二阶段提交成功").build();
    }

    @Override
    public OperationResponse phaseTwoRollback(String xid) {
        DynamicDataSourceContextHolder.routeMaster();
        MergeAction action = mergeLogService.queryMergeAction(xid);
        phaseTwoTransactionHandler.rollback(action);
        return OperationResponse.builder().success(true).message("二阶段补偿成功").build();
    }
}
